Skip to content

fix(events): match listing duplicates by headliner and venue identity - #3966

Merged
chubes4 merged 6 commits into
mainfrom
fix/listings-dedup-3965
Nov 15, 2026
Merged

chubes4 merged 6 commits into
mainfrom
fix/listings-dedup-3965

Conversation

@chubes4

@chubes4 chubes4 commented Nov 15, 2026 •

Copy link
Copy Markdown
Member

Closes #3965

Problem

The mosplaceradio.com/bandschedules listings import (flow 983, job 1986789) created 341 events and matched 0 existing ones. The AI step sends a venue name plus city/state with no street address, titles like Headliner with Support at Venue, and loose venue names. Two gaps:

  1. Venue resolution (Venue_Taxonomy::resolve_venue_identity): Iron Horse Music Hall vs The Iron Horse, Paradise Rock Club vs Paradise Rock Club presented by Citizens, Roadrunner vs Roadrunner-Boston, John F. Swope Theater, Capitol Center for the Arts vs Capitol Center for the Arts. The exact, article and normalized tiers miss these, and the core-name tier needs exact core equality. Result: about 100 new venue terms.
  2. Event dedup (EventDuplicateStrategy): even on the same venue term, the fuzzy title check compares full titles (fantastic cat at iron horse music hall vs fantastic cat at iron horse 2 shows, hunxho vs hunxho 2night only tour), so the result was CLEAR.

Fix

  • Venue_Taxonomy: new venue_variant_key() and venue_names_are_variants(), built on core_venue_name(). They strip "presented/powered/sponsored/hosted by …", a trailing parenthetical, a "-" suffix, a trailing "music hall", and a standalone "at", and also accept a multi-word prefix or a Room, Venue comma part. resolve_core_name_tier() accepts these variants only when the incoming venue has no street address and has a city. It still requires has_positive_location_evidence(). More than one compatible term returns ambiguous (no term is created). A match reports matched_via = name_variant.
  • EventDuplicateStrategy: new Strategy 2b, findByHeadlinerAndVenueIdentity(). It compares headlinerKey() (strips " at " or a venue variant, support/co-bill lists, tour or ":" subtitles, and accents; keeps "Late Show" / "Night 2" set names) for same-day candidates at the same venue term or at a same-city name-variant term. Time window: the normal window, or the strict one-hour window for low-confidence keys. Outside the window, a single cross-source candidate is accepted (mirrors Strategy 2), except for low-confidence keys at a variant venue.

Prod evidence (read-only simulation over the 82 already-trashed duplicates from this import)

  • Before: 4/82 detected. After: 56/82 detected.
  • On 289 surviving events from the same import: 4 new hits, all genuine duplicates. One of them, Tusk at the Academy of Music, has since been trashed manually.
  • Venue scan: re-resolving all 110 import-created venue terms with those terms hidden gives 15 name_variant matches, 0 ambiguous, and none across cities. Examples: Roadrunner → Roadrunner-Boston, The Sinclair → The Sinclair Music Hall, The Drake → The Drake - Amherst, Brighton Music Hall → … presented by Citizens. Two are room- or stage-level merges, allowed by the prefix rule: Off the Rails (Worcester) → Off The Rails Outdoors, and Arts at the Armory Cafe → Arts at the Armory.
  • Deliberately unmatched: Angela Autumn at Rockwell (Boston) vs Rockwell - MA (Somerville), because the cities differ.

Tests

  • tests/Unit/EventDuplicateHeadlinerVenueTest.php: Hunxho/Big Night Live tour suffix (same time and cross-source), Whitechapel support list, Iron Horse variant venue, Béla Fleck accents with a room-qualified venue, Street Dogs sponsor variant. Negatives: different headliners at different venues, same headliner at two different same-city venues, Open Mic at X vs Open Mic at Y, same headliner in a different city, one-word headliner at a variant venue outside the window. Plus headlinerKey() cases.
  • tests/Unit/VenueTaxonomyListingVariantTest.php: Iron Horse Music Hall + Northampton, MA resolves to The Iron Horse (name_variant). Variant data provider. Two-term ambiguous case. Other-city, no-city and street-address negatives. Single-word-prefix negative.

Left out

  • Accented venue term fixtures in PHPUnit: the WP Codebox SQLite test DB returns no get_terms() rows once such a term exists. Accent folding is covered via headlinerKey() tests and was verified on prod MySQL (e.g. Esme Hotel Rooftop Music Hall → Esmé Hotel Rooftop).
  • Venue keys shorter than 5 chars (Ciné) are never treated as variants (existing FUZZY_NAME_MIN_LENGTH).
  • Venues whose names share no variant relation (Wilbur Theatre vs Hava Nightclub, Off the Rails Worcester vs Off The Rails Boston, House of Blues - Boston vs Citizens House of Blues Boston, sponsor prefixes) stay unmatched on purpose.
  • Merging the existing duplicate venue terms and events on prod is a separate data-cleanup job.

Written by Extra Chill Bot (AI agent) on behalf of Chris Huber.

homeboy-ci Bot added 6 commits November 15, 2026 14:52
Multi-venue listing imports title shows 'Headliner with Support at Venue'
and name venues loosely ('Iron Horse Music Hall' for 'The Iron Horse').
Add a headliner + venue-identity duplicate strategy and resolve
address-less same-city venue name variants to the existing term,
reporting ambiguity when more than one term matches.

Closes #3965
@chubes4
chubes4 merged commit 767a6d7 into main Nov 15, 2026
3 checks passed
@chubes4
chubes4 deleted the fix/listings-dedup-3965 branch November 15, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(events): listings import duplicates directly-scraped events (venue name variants, headliner suffixes)

1 participant